package server;

import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Vector;

/**
 * Auction: An Auction
 * 	Managed by AuctionManager
 * 	Properties: Unique ID, Name (or Description), Duration
 * 
 * @author Fleischhacker
 *
 */
public class Auction {
	
	/**
	 * Unique ID, given by AuctionManager
	 */
	private int id;
	
	/**
	 * Description of the Subject
	 */
	private String description;
	
	/**
	 * Date/Timestamp of the End of the Auction
	 */
	private Date timestamp;
	
	/**
	 * Is auction active?
	 */
	private boolean active;
	
	/**
	 * The top Bidder of the Auction
	 * Null if no Bidder
	 */
	private User topBidder;
	
	/**
	 * List of all (incl. current top-)Bidders
	 */
	private Vector<User> bidderlist;

	/**
	 * Top bid from the topBidder
	 * 
	 */
	private double topBid;
	
	/**
	 * The owner who offered the Auction
	 */
	private User owner;
	
	public Auction(int _id, String _description, User _owner, int time){
		id = _id;
		this.description = _description;
		this.owner = _owner;
		this.timestamp = new Date(((long)new Date().getTime() + time*1000));
		this.topBidder = null;
		this.topBid = 0.00;
		this.bidderlist = new Vector<User>();
		active = true;
	}
	
	/**
	 * Returns ID of the Auction
	 * @return
	 */
	public int getID(){
		return id;
	}
	
	/**
	 * Returns the End-Date of the Auction
	 * @return
	 */
	public String getEndDateString(){
		//return timestamp.getYear()+"-"+timestamp.getMonth()+"-"+timestamp.getDay()+" "+timestamp.getHours()+":"+timestamp.getMinutes();
		//return new SimpleDateFormat("yyyy/mm/dd").format(timestamp);
		return new SimpleDateFormat("yyyy-MM-dd' 'HH:mm").format(timestamp);
	}
	
	/**
	 * Returns Description
	 * @return
	 */
	public String getDescription(){
		return new String(this.description);
	}
	
	/**
	 * 
	 * @return
	 */
	public User getOwner(){
		return this.owner;
	}
	
	/**
	 * returns the state if it's still ongoing or has ended already
	 * @return
	 */
	public boolean isActive(){
		return active;
	}
	
	/**
	 * Checks timestamp (if auction is still valid)
	 * if auction is not valid -> set active false
	 * @param _now
	 * @return
	 */
	public boolean checkAuctionEnded(Date _now){
		if(_now.after(timestamp)){
			active = false;
			return true;
		}
		return false;
	}
	
	/**
	 * Override toString
	 */
	public String toString(){
		String ret = "";
		ret += id+" ~ ";
		ret += description+"~ ";
		ret += getEndDateString()+" ~ ";
		ret += owner.getScreenname()+" ~ ";
		ret += getBidString()+" ~ ";
		if(topBidder == null)
			ret += "none";
		else
			ret += topBidder.getScreenname();
		return ret;
	}
	
	/**
	 * Returns the Bid as String (altered Output)
	 * @return
	 */
	public String getBidString(){
		NumberFormat nf = NumberFormat.getNumberInstance();
		nf.setMinimumFractionDigits(2);
		nf.setMaximumFractionDigits(2);
		return nf.format(topBid);
	}
	
	public double getBid(){
		return this.topBid;
	}
	
	/**
	 * Returns the current Top-Bidder
	 * @return
	 */
	public User getCurrentTopBidder(){
		return this.topBidder;
	}
	
	/**
	 * Tries to overbid the old Bidder with a new Bid
	 * @return	true if new bid overbed old one
	 * 			false otherwise
	 */
	public boolean overBid(User _bidder, double _bid){
		addBidderToList(_bidder);
		synchronized(this){
			if(_bid > this.topBid){
				this.topBidder = _bidder;
				this.topBid = _bid;
				return true;
			}
		}
		return false;
	}
	
	/**
	 * Adds User to Bidder-List (for Notification Purposes)
	 * @param _user
	 */
	private void addBidderToList(User _user){
		synchronized(this){
			boolean has = false;
			for(User u : bidderlist){
				if(u.getScreenname().equalsIgnoreCase(_user.getScreenname()))
					has = true;
			}
			if(!has)
				bidderlist.add(_user);
		}
	}
	
	/**
	 * Returns a List of Bidders for this Auction
	 * @return
	 */
	public List<User> getBidderList(){
		ArrayList<User> al = new ArrayList<User>();
		for(User u : bidderlist){
			al.add(u);
		}
		return al;
	}
}
